package com.hxt.xt.service.base;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.hxt.framework.manager.RetCodeManager;
import com.hxt.framework.msg.ResponseMsg;
import com.hxt.framework.service.BaseService;
import com.hxt.framework.utils.DateUtil;
import com.hxt.framework.utils.JpException;
import com.hxt.util.TypeConvert;
import com.hxt.xt.model.ExceptionLog;
import com.hxt.xt.service.z.rule.BaseRule;

@Component
public class BaseMgr extends BaseService {

	@Resource
	protected BaseRule rule;

	@Resource
	private JtaTransactionManager txManager;

	/**
	 * @Title: bigenTransaction
	 * @Description: 开启事务
	 * @param definition
	 * @return
	 * @return: TransactionStatus
	 */
	protected TransactionStatus txBegin(Integer definition) {
		txManager.setRollbackOnCommitFailure(true);
		Integer tdf = null;
		if (definition == null) {
			tdf = TransactionDefinition.PROPAGATION_REQUIRED;
		} else {
			tdf = definition;
		}
		TransactionStatus txstatus = txManager.getTransaction(new DefaultTransactionDefinition(tdf.intValue()));
		return txstatus;
	}

	/**
	 * @Title: commitTransaction
	 * @Description: 事务提交
	 * @param status
	 * @return: void
	 */
	protected void txCommit(TransactionStatus txstatus) {
		txManager.commit(txstatus);
	}

	/**
	 * @Title: rollbackTransaction
	 * @Description: 事务回滚
	 * @param status
	 * @return: void
	 */
	protected void txRollback(TransactionStatus txstatus) {
		txManager.rollback(txstatus);
	}

	public void writeExceptionLog(final String txit, final String param, final String err) {

		final ExecutorService executor = Executors.newCachedThreadPool();
		executor.submit(new Callable<Object>() {
			@Override
			public Object call() {
				try {
					// 记录异常日志
					ExceptionLog log = new ExceptionLog();
					log.setCreateTime(TypeConvert.intTolong(DateUtil.getToday()));
					log.setOrganID(1);
					log.setReqUrl(txit);
					log.setReqParam(param);
					log.setRemark(err);

					TransactionStatus txStatus = txBegin(3);// 开启事务
					rule.exceptionLogDao.saveObject(log);
					txCommit(txStatus);// 提交事务
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}
		});

	}

	public static final String succes = "200";
	public static final String fail = "400";

	/**
	 * @Title: handleException
	 * @Description: 异常处理时返回值处理
	 * @param t
	 * @param e
	 * @return
	 * @return: T
	 */
	protected ResponseMsg<?> handleException(ResponseMsg<?> t, Throwable e) {
		writeExceptionLog("", "", toString_02(e));
		if (e instanceof JpException) {
			return setResCode(t, (JpException) e);
		} else if (e instanceof java.net.UnknownHostException) {
			return setResCode(t, "SYS-101");
		} else if (e instanceof java.net.UnknownServiceException) {
			return setResCode(t, "SYS-101");
		} else if (e instanceof java.sql.SQLException) {
			return setResCode(t, "SYS-102");
		} else if (e instanceof java.sql.SQLFeatureNotSupportedException) {
			return setResCode(t, "SYS-102");
		} else if (e instanceof IOException) {
			return setResCode(t, "SYS-103");
		} else {

			return setResCode(t, "SYS-104");
		}
	}

	
	   private static String toString_02(Throwable e){   
           StringWriter sw = new StringWriter();   
           PrintWriter pw = new PrintWriter(sw, true);   
           e.printStackTrace(pw);   
           pw.flush();   
           sw.flush();   
           return sw.toString();   
   } 
	   
	/**
	 * @Description: TODO
	 */
	protected ResponseMsg<?> setResCode(ResponseMsg<?> t, String code) {
		RetCodeManager.getGlobal().setErroCode(t, code);
		return t;
	}

	protected ResponseMsg<?> setFailRet(ResponseMsg<?> t, String retMsg) {
		return setFailRet(t, fail, retMsg);
	}

	protected ResponseMsg<?> setFailRet(ResponseMsg<?> t, String retCode, String retMsg) {
		t.setRetCode(retCode);
		t.setRetMsg(retMsg);
		return t;
	}

	/**
	 * @Title: setResCode
	 * @Description: 设置返回码
	 */
	protected ResponseMsg<?> setResCode(ResponseMsg<?> t, JpException e) {
		t.setRetCode(e.getErrCode());
		t.setRetMsg(e.getErrMsg());
		return t;
	}

}
